package de.jmda.core.mproc;

import static de.jmda.core.mproc.ProcessingUtilities.asDeclaredType;
import static de.jmda.core.mproc.ProcessingUtilities.getFields;
import static de.jmda.core.mproc.ProcessingUtilities.getTypeElement;
import static de.jmda.core.mproc.ProcessingUtilities.isPrimitiveKind;
import static de.jmda.core.util.CollectionsUtil.asSet;

import java.io.IOException;
import java.util.List;
import java.util.Set;

import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;

import org.junit.Test;

import de.jmda.core.MarkerAnnotationType;
import de.jmda.core.mproc.task.AbstractTypeElementsTaskTypes;
import de.jmda.core.mproc.task.TaskException;
import de.jmda.core.mproc.task.TaskRunner;

public class JUTDeclaredType
{
	@MarkerAnnotationType
	private class DeclaredTypeContainer
	{
		@SuppressWarnings("unused")
    int i;
		@SuppressWarnings("unused")
    String s;
		@SuppressWarnings("unused")
    List<DeclaredTypeContainer> t;
	}

	private class Task extends AbstractTypeElementsTaskTypes
	{
		private TypeElement type;

		private Task(Set<? extends Class<?>> types)
		{
			super(types);
		}

		@Override
		public boolean execute() throws TaskException
		{
			type = getTypeElement(DeclaredTypeContainer.class);
			return false;
		}
	}

	@Test
	public void test() throws IOException
	{
		Task task = new Task(asSet(DeclaredTypeContainer.class));
		TaskRunner.run(task);
		
		for (VariableElement field : getFields(task.type))
		{
			DeclaredType declaredType = asDeclaredType(field.asType());

			String s = 
					"declared type: " + declaredType + "\n" +
			    "primitive:     " + isPrimitiveKind(field);
			
			if (declaredType != null)
			{
				s += "\n# type args: " + declaredType.getTypeArguments().size();
			}

			System.out.println(s);
		}
	}
}